//CacheMaintainer
package main

import (
	"container/heap"
	"os"
	//"sort"
	"io"
	"log"
	"net/http"
	"path"
	"time"
)

var Ticker *time.Ticker

func CacheMaintainer(ticker *time.Ticker) {
	for _ = range ticker.C {

		log.Println("Running Cache Maintainer")
		var NewBestHundreda CachedImages = make([]*Cacheitem, 0)
		var NewBestHundred *CachedImages = &NewBestHundreda

		heap.Init(NewBestHundred)
		for _, value := range Cache {
			value.score = value.score - ScoreReduce

			if value.score <= 0 {
				delete(Cache, value.name)
				log.Println("Deleted", value.name, "from cache db: Score below zero")
			} else {
				if value.faulty == nil && value.cacheable == true {
					heap.Push(NewBestHundred, value)
					log.Println("Put", value.name, "onto NewHeap")
					if len(NewBestHundreda) > 100 {
						popped := heap.Pop(NewBestHundred)
						log.Println("Popped", popped.(*Cacheitem).name, "from NewHeap")
					}
				} else {
					log.Println("Not putting", value.name, "onto NewHeap; faulty/not cacheable")
				}
			}

		}

		if Cachedimages != nil {
			for _, value := range *Cachedimages {
				var exists bool

				for _, value2 := range NewBestHundreda {
					if value == value2 {
						exists = true
						break
					}
				}

				if !exists {
					log.Println("Throwing", value.name, "out of cache")
					value.incache = false
					value.data = nil
				}

			}
		}
		//TODO: all NewBestHundred to Cached and get the data!

		for _, value := range NewBestHundreda {
			if value.incache == false {
				if value.faulty == nil && value.cacheable == true {
					log.Println("Putting", value.name, "into cache")
					value.incache = true
					file, _ := os.Open(path.Join(Basedir, value.relpath))
					//fstat, _ := file.Stat()
					//value.data = make([]byte, fstat.Size())
					//buf := bytes.NewBuffer(value.data)
					//io.Copy(buf, file)

					fstat, _ := file.Stat()
					value.data = make([]byte, fstat.Size())
					io.ReadFull(file, value.data)
					value.contenttype = http.DetectContentType(value.data)
				} else {
					log.Println("Ignoring", value.name, "for cache: faulty/not cacheable")
				}
			}
		}

		Cachedimages = NewBestHundred
		log.Println("Cache Maintainer finished")
	}
}

func StartCacheMaintainer() {
	Ticker = time.NewTicker(MaintainerTick)

	go CacheMaintainer(Ticker)
}
